package clientN

import (
	"bufio"
	"log"
	"net"
	"sync"
	"time"
	"wxp2p/common"
)

// 远程连接<-->local:2222<-->client_client<-->webrtcdatachannel<-->server_client<-->local:3389

type TCPServer struct {
	id_conn_map_nutex sync.RWMutex
	id_conn_map       map[string]net.Conn
	port              string
	host              string
	dataChannel       *WebrtcAnswer
}

func NewTCPServer(host string, port string, dc *WebrtcAnswer) *TCPServer {
	tc := TCPServer{host: host, port: port, dataChannel: dc}
	tc.id_conn_map = make(map[string]net.Conn)
	tc.id_conn_map_nutex = sync.RWMutex{}
	return &tc
}

func (ts *TCPServer) ServerRecvChanHandler(buf []byte) {
	id, action, content := common.UnPackageData(buf)
	switch action {
	case "data":
		ts.id_conn_map_nutex.RLock()
		conn, bHave := ts.id_conn_map[id]
		ts.id_conn_map_nutex.RUnlock()
		if bHave {
			_, err := conn.Write([]byte(content))
			if err != nil {
				log.Println(err)
				ts.id_conn_map_nutex.Lock()
				delete(ts.id_conn_map, id)
				ts.id_conn_map_nutex.Unlock()
				ts.dataChannel.DataSendChan <- common.PackageData(id, "close", "")
			}
		} else {
			log.Println("1.出错了，应该存在的连接失败了")
		}
	case "new":
		conn, err := net.DialTimeout("tcp", ts.host+":"+ts.port, 2*time.Second)
		if err != nil {
			log.Println("dial error:", err)
			return
		}
		ts.id_conn_map_nutex.Lock()
		ts.id_conn_map[id] = conn
		ts.id_conn_map_nutex.Unlock()
		// 接收数据的线程,接收2222的数据
		go func() {
			buf := make([]byte, 60535)
			reader := bufio.NewReader(conn)
			defer func() {
				conn.Close()
				ts.id_conn_map_nutex.Lock()
				delete(ts.id_conn_map, id)
				ts.id_conn_map_nutex.Unlock()
				ts.dataChannel.DataSendChan <- common.PackageData(id, "close", "")
			}()
			for {
				cnt, err := reader.Read(buf)
				if cnt == 0 || err != nil {
					break
				}
				ts.dataChannel.DataSendChan <- common.PackageData(id, "data", string(buf[0:cnt]))
			}
		}()
	case "close":
		ts.id_conn_map_nutex.RLock()
		conn, bHave := ts.id_conn_map[id]
		ts.id_conn_map_nutex.RUnlock()
		if bHave {
			conn.Close()
			ts.id_conn_map_nutex.Lock()
			delete(ts.id_conn_map, id)
			ts.id_conn_map_nutex.Unlock()
		} else {
			log.Println("2.出错了，应该存在的连接失败了")
		}
	}
}
